By default, S3 buckets can be accessed through HTTP and HTTPs protocols.
As HTTP is a clear-text protocol, it lacks the encryption of transported data, as well as the capability to build an authenticated connection. It
means that a malicious actor who is able to intercept traffic from the network can read, modify or corrupt the transported content.
Ask Yourself Whether
- The S3 bucket stores sensitive information.
- The infrastructure has to comply with AWS Foundational Security Best Practices standard.
There is a risk if you answered yes to any of those questions.
Recommended Secure Coding Practices
It’s recommended to deny all HTTP requests:
- for all objects (
*
) of the bucket
- for all principals (
*
)
- for all actions (
*
)
Sensitive Code Example
No secure policy is attached to this S3 bucket:
AWSTemplateFormatVersion: 2010-09-09
Resources:
S3Bucket:
Type: 'AWS::S3::Bucket' # Sensitive
A policy is defined but forces only HTTPs communication for some users:
AWSTemplateFormatVersion: 2010-09-09
Resources:
S3Bucket:
Type: 'AWS::S3::Bucket' # Sensitive
Properties:
BucketName: "bucketname"
S3BucketPolicy:
Type: 'AWS::S3::BucketPolicy'
Properties:
Bucket: !Ref S3Bucket
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Deny
Principal:
AWS: # Sensitive: only one principal is forced to use https
- 'arn:aws:iam::123456789123:root'
Action: "*"
Resource:
- arn:aws:s3:::bucketname
- arn:aws:s3:::bucketname/*
Condition:
Bool:
"aws:SecureTransport": false
Compliant Solution
A secure policy that denies the use of all HTTP requests:
AWSTemplateFormatVersion: 2010-09-09
Resources:
S3Bucket:
Type: 'AWS::S3::Bucket' # Compliant
Properties:
BucketName: "bucketname"
S3BucketPolicy:
Type: 'AWS::S3::BucketPolicy'
Properties:
Bucket: !Ref S3Bucket
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Deny
Principal:
AWS: "*" # all principals should use https
Action: "*" # for any actions
Resource: # for the bucket and all its objects
- arn:aws:s3:::bucketname
- arn:aws:s3:::bucketname/*
Condition:
Bool:
"aws:SecureTransport": false
See